home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2004 #9
/
Amiga Plus CD - 2004 - No. 09.iso
/
amigaplus
/
tools
/
amigaos4_only
/
tunnel
/
tunnel.c
< prev
Wrap
C/C++ Source or Header
|
2004-08-03
|
8KB
|
336 lines
/*
** A simple tunnel for OS4
** By Peter Gordon (pete@shagged.org)
**
** Enjoy :)
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/interfaces.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/Picasso96API.h>
#include <proto/graphics.h>
#define fsqr(x) pow(x,2)
#define min(x,y) x<y ? x : y
// Libraries
struct Library *IntuitionBase = NULL;
struct Library *P96Base = NULL;
struct Library *GfxBase = NULL;
// Interfaces
struct IntuitionIFace *IIntuition;
struct P96IFace *IP96;
struct GraphicsIFace *IGraphics;
struct ExecIFace *IExec;
struct DOSIFace *IDOS;
struct Window *win;
struct BitMap *bm;
UBYTE txtr[65536*3]; // texture
UWORD uvmap[232083];
/*
** A small routine to open a library and get its default
** interface, and report errors if anything fails.
*/
BOOL getLibIFace( struct Library **libbase, char *libname, int version, struct Interface **ifaceptr )
{
*libbase = IExec->OpenLibrary( libname, version );
if( *libbase == NULL )
{
printf( "Unable to open '%s' version %d\n", libname, version );
return FALSE;
}
*ifaceptr = IExec->GetInterface( *libbase, "main", 1, NULL );
if( *ifaceptr == NULL )
{
printf( "Unable to get the main interface for '%s'\n", libname );
return FALSE;
}
return TRUE;
}
BOOL init( void )
{
BPTR h;
if( !getLibIFace( &IntuitionBase, "intuition.library", 50, (struct Interface **)&IIntuition ) ) return FALSE;
if( !getLibIFace( &GfxBase, "graphics.library", 48, (struct Interface **)&IGraphics ) ) return FALSE;
if( !getLibIFace( &P96Base, "Picasso96API.library", 2, (struct Interface **)&IP96 ) ) return FALSE;
h = IDOS->Open( "texture.raw", MODE_OLDFILE );
if( !h )
{
printf( "Unable to open texture.raw\n" );
return FALSE;
}
IDOS->Read( h, txtr, 65536*3 );
IDOS->Close( h );
bm = IP96->p96AllocBitMap( 320, 240, 24, 0, NULL, RGBFB_R8G8B8 );
if( !bm ) return FALSE;
win = IIntuition->OpenWindowTags( NULL,
WA_Left, 28,
WA_Top, 28,
WA_InnerWidth, 320,
WA_InnerHeight, 240,
WA_Title, "Wheeeee !",
#ifdef PLANES
WA_ScreenTitle, "Planes Demo ©2004 Peter Gordon (pete@shagged.org)",
#else
#ifdef BOXTUNNEL
WA_ScreenTitle, "BoxTunnel Demo ©2004 Peter Gordon (pete@shagged.org)",
#else
#ifdef QUADPLANE
WA_ScreenTitle, "Quadplane Demo ©2004 Peter Gordon (pete@shagged.org)",
#else
WA_ScreenTitle, "Tunnel Demo ©2004 Peter Gordon (pete@shagged.org)",
#endif
#endif
#endif
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_Activate, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW,
TAG_DONE );
if( !win ) return FALSE;
return TRUE;
}
void shutdown( void )
{
if( win ) IIntuition->CloseWindow( win );
if( bm ) IP96->p96FreeBitMap( bm );
if( P96Base ) IExec->CloseLibrary( P96Base );
if( GfxBase ) IExec->CloseLibrary( GfxBase );
if( IntuitionBase ) IExec->CloseLibrary( IntuitionBase );
}
// Cam Rotate Y, Cam Rotate Z, Cam position Z
void tunnel( double cry, double crz, double cz )
{
double len,vx,vy,vz;
double dx,dy,dz;
double a,delta,t;
double fx,ys,yc,zs,zc,ys2,yc2;
ULONG pk,px,py,lock;
UWORD tu,tv,tm;
ULONG u1, u2, v1, v2, d1, d2;
UBYTE *bptr;
struct RenderInfo rinf;
ys = sin( cry );
ys2 = ys*256;
yc = cos( cry );
yc2 = yc*256;
zs = sin( crz );
zc = cos( crz );
pk = 0;
for( py=0; py<31; py++ )
{
for( px=0; px<41; px++ )
{
dx = (double)(px<<3)-160;
dy = (double)(py<<3)-122;
fx = zs*dy+zc*dx; // Rotate around Z axis
dy = zc*dy-zs*dx; // Rotate around Y axis
dx = yc*fx-ys2;
dz = ys*fx+yc2;
#ifdef PLANES
a = fsqr(dx);
#else
#ifdef BOXTUNNEL
a = abs(dx) < abs(dy) ? fsqr(dy) : fsqr(dx);
#else
#ifdef QUADPLANE
a = abs(dx) < abs(dy) ? fsqr(dx) : fsqr(dy);
#else
a = (fsqr(dx) + fsqr(dy));
#endif
#endif
#endif
if( a >= 0 )
{
delta = a*131072;
t = -fabs( sqrt( delta )/a );
vx = dx*t;
vy = dy*t;
vz = dz*t;
tm = ((UWORD)fabs(t*10));
uvmap[ pk++ ] = (UWORD)(fabs(vz+cz)*0.2);
uvmap[ pk++ ] = (UWORD)(fabs(atan2(vy,vx)*81.4873309));
uvmap[ pk ] = 256 - (min( tm, 256 ));
pk+=22;
} else pk+=24;
}
pk += 6720;
}
pk=0;
// Interpolate down
for( py=0; py<30; py++ )
{
for( px=0; px<41; px++ )
{
u2 = uvmap[pk];
u1 = uvmap[pk+7704]-u2;
u2 = (u2<<3) + u1;
v2 = uvmap[pk+1];
v1 = uvmap[pk+7705]-v2;
v2 = (v2<<3) + v1;
d2 = uvmap[pk+2];
d1 = uvmap[pk+7706]-d2;
d2 = (d2<<3) + d1;
for( tu=963; tu<7704; tu+=963 )
{
uvmap[pk+tu] = u2>>3;
uvmap[pk+tu+1] = v2>>3;
uvmap[pk+tu+2] = d2>>3;
u2 += u1;
v2 += v1;
d2 += d1;
}
pk += 24;
}
pk += 6720;
}
pk = 0;
// Interpolate across
for( py=0; py<240; py++ )
{
for( px=0; px<40; px++ )
{
u2 = uvmap[pk++];
u1 = uvmap[pk+23]-u2;
u2 = (u2<<3) + u1;
v2 = uvmap[pk++];
v1 = uvmap[pk+23]-v2;
v2 = (v2<<3) + v1;
d2 = uvmap[pk++];
d1 = uvmap[pk+23]-d2;
d2 = (d2<<3) + d1;
for( tu=1; tu<8; tu++ )
{
uvmap[pk++] = u2>>3;
uvmap[pk++] = v2>>3;
uvmap[pk++] = d2>>3;
u2 += u1;
v2 += v1;
d2 += d1;
}
}
pk+=3;
}
lock = IP96->p96LockBitMap( bm, (UBYTE *)&rinf, (ULONG)sizeof( struct RenderInfo ) );
if( !lock ) return;
bptr = (UBYTE *)rinf.Memory;
for( py=0; py<231120; py+=963 )
{
u1 = py;
for( px=0; px<320; px++ )
{
tv = (((uvmap[u1++]&255)<<8)|(uvmap[u1+1]&255))*3;
tm = (UBYTE)((txtr[tv++]*uvmap[++u1])>>8);
*(bptr) = (*(bptr++)+tm)>>1;
tm = (UBYTE)((txtr[tv++]*uvmap[u1])>>8);
*(bptr) = (*(bptr++)+tm)>>1;
tm = (UBYTE)((txtr[tv++]*uvmap[u1++])>>8);
*(bptr) = (*(bptr++)+tm)>>1;
/*
*(bptr++) = (UBYTE)((txtr[tv++]*uvmap[++u1])>>8);
*(bptr++) = (UBYTE)((txtr[tv++]*uvmap[u1])>>8);
*(bptr++) = (UBYTE)((txtr[tv++]*uvmap[u1++])>>8);
*/
}
}
IP96->p96UnlockBitMap( bm, lock );
}
int main( void )
{
struct DateStamp start_ds, end_ds;
ULONG frames = 0, ticks;
if( init() )
{
BOOL done = FALSE;
ULONG wsig, sigs;
struct IntuiMessage *msg;
double cry, crz, cz;
wsig = (1L<<win->UserPort->mp_SigBit);
IDOS->DateStamp( &start_ds );
while( !done )
{
// IGraphics->WaitTOF();
tunnel( cry, crz, cz );
IGraphics->BltBitMapRastPort( bm, 0, 0, win->RPort, win->BorderLeft, win->BorderTop, 320, 240, 0x0C0 );
cry += 0.03;
crz -= 0.01;
cz -= 80;
sigs = IExec->SetSignal( 0L, 0L );
frames++;
if( sigs & SIGBREAKF_CTRL_C ) done = TRUE;
if( sigs & wsig )
{
while( msg = (struct IntuiMessage *)IExec->GetMsg( win->UserPort ) )
{
if( msg->Class == IDCMP_CLOSEWINDOW ) done = TRUE;
IExec->ReplyMsg( (struct Message *)msg );
}
}
}
IDOS->DateStamp(&end_ds);
ticks = (end_ds.ds_Days-start_ds.ds_Days) * 86400*TICKS_PER_SECOND
+(end_ds.ds_Minute-start_ds.ds_Minute) * 60*TICKS_PER_SECOND
+(end_ds.ds_Tick-start_ds.ds_Tick);
printf( "FPS: %d\n", (TICKS_PER_SECOND * frames) / ticks+1 );
}
shutdown();
return 0;
}